#pragma once

#include "zen_app.h"
#include "zen_ticker.h"
#include <vector>
#include <mutex>
#include "zen_game_touch.h"
#include "zen_game_action.h"
#include "zen_game_node.h"
#include "zen_game_texture.h"

namespace Zen
{
	namespace Game
	{
		class ActivityDelegate
		{
		public:
			virtual void OnLaunch() {}

			virtual void OnResize() {}

			virtual void OnPause() {}

			virtual void OnResume() {}

			virtual void OnExit() {}

			virtual void OnEvent(std::string event) {}
		};

		class Activity : public AppDelegate
		{
		public:
			static std::shared_ptr<Activity> Only();

		public:
			/*!
			 - call SetDelegate in `ZenAppMain` entrance.
			 */
			virtual void InitGraphicsEngine(std::shared_ptr<Zen::Graphics::Engine> _) = 0;
			virtual void InitDelegate(std::shared_ptr<ActivityDelegate> _) = 0;

			virtual auto GetDelegate() -> std::shared_ptr<ActivityDelegate> = 0;

			virtual std::shared_ptr<Zen::Graphics::Engine> GetGraphicsEngine() = 0;

		public: // below functions not valid before OnLaunch.
			virtual Point2 GetScreenSize() = 0;

		public: // game time
			virtual double GetRunningTime() = 0;
			virtual double GetActivityTime() = 0;

			virtual double GetRealFPS() = 0;

		public:
			virtual auto GetRoot() -> std::shared_ptr<Node> = 0;

			virtual TouchDispatcher* GetTouchDispatcher() = 0;

			virtual ActionDispatcher* GetActionDispather() = 0;

		protected:
			Activity() = default;

			virtual ~Activity() = default;
		};

		inline std::shared_ptr<Zen::Graphics::Buffer> NewBuffer()
		{
			return Activity::Only()->GetGraphicsEngine()->GenerateBuffer();
		}

		inline std::shared_ptr<Zen::Graphics::IndexBuffer> NewIndexBuffer()
		{
			return Activity::Only()->GetGraphicsEngine()->GenerateIndexBuffer();
		}
	} // namespace Game
} // namespace Zen
